package com.xs.ahoi.hcxs.model.vo;

import android.graphics.Paint;
import com.xs.ahoi.hcxs.utils.Constants;
import com.xs.ahoi.hcxs.utils.ObjectUtils;
import com.xs.ahoi.hcxs.utils.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * author: ahoi
 * date: 2018/7/10 13:47
 * description: 行内字符数据
 */
public class CharData {

    // 字符
    private String c;

    // 是否选中
    private boolean isSelected = false;

    // 字符宽度
    private int charWidth;

    // 四个角的坐标
    private float left;
    private float right;
    private float top;
    private float bottom;


    // 获取文字转化为CharData
    public static List<CharData> getCharDatas(String line, Paint paint, int startx, int starty) {
        List<CharData> charDatas = new ArrayList<>();
        CharData charData;
        String c;
        int leftX = startx, rightX, topY, bottomY, charWidth;
        int descent = (int) paint.getFontMetrics().descent;
        int ascent = (int) paint.getFontMetrics().ascent;
        for (int i = 0; i < line.length(); i++) {
            charData = new CharData();
            c = line.substring(i, i + 1);

            // 测量文字宽度
            charWidth = (int) paint.measureText(c);
            topY = starty + ascent;
            bottomY = starty + descent;
            rightX = leftX + charWidth;

            charData.setC(c);
            charData.setCharWidth(charWidth);
            charData.setLeft(leftX);
            charData.setRight(rightX);
            charData.setTop(topY);
            charData.setBottom(bottomY);
            charDatas.add(charData);

            // 将本次的右边x坐标 给 下次的左边x坐标
            leftX = rightX;
        }
        return charDatas;
    }

    // 查找拖动位置附近的文字
    public static CharData getPointMove(float pressX, float pressY, List<PageCharData> pageCharDatas) {
        CharData prevOne = null;
        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> rowData = pageCharData.getCharData();

            // 如果触摸位置的Y坐标在本行数据的TOP上面，则停止继续搜索
            if (pressY < rowData.get(0).getTop()) {
                break;
            }

            // 如果触摸位置X左边在本行最后一个字符的右边，则标记结果为最后一个字符
            CharData lastOne = rowData.get(rowData.size() - 1);
            if (pressX > lastOne.getRight()) {
                prevOne = lastOne;
            }

            // 查询本行中字符的left,right包含了触摸位置X坐标的字符，标记为已找到
            for (CharData data : rowData) {
                if (pressX > data.getLeft() && pressX <= data.getRight()) {
                    prevOne = data;
                    break;
                }
            }
        }
        try {
            // 如果没找到，就取第一个字，防止顶部滑动溢出
            if (prevOne == null) {
                prevOne = pageCharDatas.get(0).getCharData().get(0);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
//        if (prevOne != null) {
//            prevOne.setSelected(true);
//        }
        return prevOne;
    }

    // 查找按下位置附近的文字
    public static CharData getPointPress(float pressX, float pressY, List<PageCharData> pageCharDatas) {
        CharData prevOne = null;
        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> rowData = pageCharData.getCharData();

            // 如果触摸位置的Y坐标在本行数据的TOP上面，则停止继续搜索
            if (pressY < rowData.get(0).getTop()) {
                break;
            }

            // 如果位于当前行的下方，则跳过本行
            if (pressY > rowData.get(0).getBottom()) {
                continue;
            }

            // 查询本行中字符的left,right包含了触摸位置X坐标的字符，标记为已找到
            for (CharData data : rowData) {
                if (pressX > data.getLeft() && pressX <= data.getRight()) {
                    prevOne = data;
                    break;
                }
            }
        }
        if (prevOne != null) {
            prevOne.setSelected(true);
        }
        return prevOne;
    }

    // 查找首尾字符之间的文字
    public static List<CharData> listBetweenFirstAndLast(CharData first, CharData last, List<PageCharData> pageCharDatas) {
        List<CharData> result = new ArrayList<>();

        // 重置已选文字
        resetSelected(pageCharDatas);

        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> charData = pageCharData.getCharData();
            for (CharData data : charData) {
                // 坐标位于第一个文字的上方，或者位于最后一个文字的下方，则代表在下一行
                if (data.getBottom() <= first.getTop() || data.getTop() >= last.getBottom()) {
                    break;
                }

                // 首尾字符在同一行，则只取中间的
                if (first.getTop() == last.getTop()) {
                    if (data.getLeft() >= first.getLeft() && data.getRight() <= last.getRight()) {
                        data.setSelected(true);
                        result.add(data);
                    }
                } else {
                    // 第一个文字右边 || 最后一个文字左边 || 中间且不在同一行
                    if ((data.getLeft() >= first.getLeft() && data.getTop() == first.getTop())
                            || (data.getRight() <= last.getRight() && data.getTop() == last.getTop())
                            || (data.getTop() >= first.getBottom() && data.getBottom() <= last.getTop())) {
                        data.setSelected(true);
                        result.add(data);
                    }
                }
            }
        }
        return result;
    }

    // 查找指定search字符前面的第一个标点符号的位置
    public static CharData getFirstByPress(List<PageCharData> pageCharDatas, CharData search) {
        List<CharData> result = new ArrayList<>();
        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> charData = pageCharData.getCharData();
            for (CharData data : charData) {
                if (data.getBottom() < search.getTop() || (data.getRight() <= search.getLeft() && data.getBottom() == search.getBottom())) {
                    result.add(data);
                }
            }
        }

        // 返回查找字符附近第一个标点符号的位置
        for (int i = result.size() - 1; i >= 0; i--) {
            CharData data = result.get(i);
            if (StringUtils.regMatch(data.getC(), Constants.REGEX_PATTERN_POINT)) {
                return (i == result.size() - 1) ? search : result.get(i + 1);
            }
        }

        // 如果没有标点符号，则返回第一个字符
        if (ObjectUtils.isNotEmpty(result)) {
            return result.get(0);
        }
        return search;
    }

    // 查找指定search字符的本段第一个字符
    public static CharData getLastByPress(List<PageCharData> pageCharDatas, CharData search) {
        List<CharData> result = new ArrayList<>();
        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> charData = pageCharData.getCharData();
            for (CharData data : charData) {
                if (data.getTop() > search.getBottom() || (data.getLeft() >= search.getRight() && data.getBottom() == search.getBottom())) {
                    result.add(data);
                }
            }
        }

        // 返回查找字符附近第一个标点符号的位置
        for (int i = 0; i < result.size(); i++) {
            CharData data = result.get(i);
            if (StringUtils.regMatch(data.getC(), Constants.REGEX_PATTERN_POINT)) {
                return i == 0 ? search : result.get(i - 1);
            }
        }

        // 如果没有标点符号，则返回最后一个字符
        if (ObjectUtils.isNotEmpty(result)) {
            return result.get(result.size() - 1);
        }
        return search;
    }

    // 重置已选文字
    private static void resetSelected(List<PageCharData> pageCharDatas) {
        for (PageCharData pageCharData : pageCharDatas) {
            List<CharData> charData = pageCharData.getCharData();
            for (CharData data : charData) {
                data.setSelected(false);
            }
        }
    }


    public String getC() {
        return c;
    }

    public void setC(String c) {
        this.c = c;
    }

    public boolean isSelected() {
        return isSelected;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
    }

    public int getCharWidth() {
        return charWidth;
    }

    public void setCharWidth(int charWidth) {
        this.charWidth = charWidth;
    }

    public float getLeft() {
        return left;
    }

    public void setLeft(float left) {
        this.left = left;
    }

    public float getRight() {
        return right;
    }

    public void setRight(float right) {
        this.right = right;
    }

    public float getTop() {
        return top;
    }

    public void setTop(float top) {
        this.top = top;
    }

    public float getBottom() {
        return bottom;
    }

    public void setBottom(float bottom) {
        this.bottom = bottom;
    }

    @Override
    public String toString() {
        return "char: " + c + "  left: " + left + "  top: " + top + "  right: " + right + "  bottom: " + bottom;
    }

    public static void main(String[] args) {
        String s = "测试<>《》！*(^)$%~!@#$…&%￥—+=、。，；‘’“”：·`文本";
        Pattern pattern = Pattern.compile("\\pP|\\pS");
        boolean b = pattern.matcher(s).find();
        System.out.println(b);
    }
}
